class Key {
    constructor(eleParent, element, color) {
        this.element = element;
        eleParent.appendChild(element);
        this.normalColor = color;

        element.addEventListener("pointerdown", this.onKeyDown);
        element.addEventListener("pointerenter", (e) => {
            if (operating) {
                this.onKeyDown(e);
            }
            e.stopPropagation();
        });
        element.addEventListener("pointerup", this.onKeyUp);
        element.addEventListener("pointerleave", (e) => {
            if (operating) {
                this.onKeyUp(e);
            }
            e.stopPropagation();
        });

        keyList.push(this);
    }

    onKeyDown = (e) => {
        this.element.style.backgroundColor = "#888";
        e.stopPropagation();
        if (!this.playing) {
            this.play();
        }
    }

    onKeyUp = (e) => {
        this.element.style.backgroundColor = this.normalColor;
        e.stopPropagation();
        this.playing = false;
    }

    play() {
        if (!this.audio) {
            this.audio = new Audio("./res/audio/" + encodeURIComponent(this.audioName) + ".mp3");
        }
        if (this.audio.ended) {
        } else {
            this.audio.currentTime = 0;
        }
        this.audio.play();
        this.playing = true;
    }
}

class WhiteKey extends Key {
    constructor(eleParent, keyName, bindKey) {
        const div = document.createElement("div");
        div.className = "key whiteKey";
        super(eleParent, div, "#fff");
        const divKeyName = document.createElement("div");
        divKeyName.innerHTML = keyName.replace("_", "");
        divKeyName.className = "keyName";
        div.appendChild(divKeyName);
        this.left = index * 22 + marginLeft;
        index++;
        div.style.left = this.left + "px";
        this.audioName = keyName;

        if (bindKey) {
            document.body.addEventListener("keydown", (e) => {
                if (e.key == bindKey || e.key == bindKey.toUpperCase()) {
                    this.onKeyDown(e);
                }
            });

            document.body.addEventListener("keyup", (e) => {
                if (e.key == bindKey || e.key == bindKey.toUpperCase()) {
                    this.onKeyUp(e);
                }
            });
        }
    }
}

class BlackKey extends Key {
    constructor(eleParent, originKey) {
        const div = document.createElement("div");
        div.className = "key blackKey";
        super(eleParent, div, "#000");
        div.style.left = originKey.left + 14 + "px";

        const originKeyName = originKey.audioName;
        const prefix = originKeyName.indexOf("_") == -1 ? "" : "_";
        this.audioName = prefix + "#" + originKeyName.replace("_", "");
    }
}

let operating = false;
let index = 0;
const keyList = [];
const marginLeft = 20;
const keyboard = document.createElement("div");
keyboard.addEventListener("pointerdown", (e) => {
    console.error
    operating = true;
}, true);
keyboard.addEventListener("pointerup", () => {
    operating = false;
}, true);
keyboard.id = "keyboard";
const A2 = new WhiteKey(keyboard, "_A2");
const B2 = new WhiteKey(keyboard, "_B2");
const _A2 = new BlackKey(keyboard, A2);
createKeyGroup(keyboard, ["_C1", "_D1", "_E1", "_F1", "_G1", "_A1", "_B1"], []);
createKeyGroup(keyboard, ["_C", "_D", "_E", "_F", "_G", "_A", "_B"], ["z", "x", "c", "v", "b", "n", "m"]);
createKeyGroup(keyboard, ["c", "d", "e", "f", "g", "a", "b"], ["a", "s", "d", "f", "g", "h", "j"]);
createKeyGroup(keyboard, ["c1", "d1", "e1", "f1", "g1", "a1", "b1"], ["q", "w", "e", "r", "t", "y", "u"]);
createKeyGroup(keyboard, ["c2", "d2", "e2", "f2", "g2", "a2", "b2"], ["1", "2", "3", "4", "5", "6", "7"]);
createKeyGroup(keyboard, ["c3", "d3", "e3", "f3", "g3", "a3", "b3"], []);
createKeyGroup(keyboard, ["c4", "d4", "e4", "f4", "g4", "a4", "b4"], []);
const c5 = new WhiteKey(keyboard, "c5");
const logo = document.createElement("div");
logo.innerHTML = "PIANO";
logo.id = "logo";
keyboard.appendChild(logo);
document.body.appendChild(keyboard);

function createKeyGroup(eleParent, keyNames, bindKey) {
    const c = new WhiteKey(eleParent, keyNames[0], bindKey[0]);
    const _c = new BlackKey(keyboard, c);
    const d = new WhiteKey(eleParent, keyNames[1], bindKey[1]);
    const _d = new BlackKey(keyboard, d);
    const e = new WhiteKey(eleParent, keyNames[2], bindKey[2]);
    const f = new WhiteKey(eleParent, keyNames[3], bindKey[3]);
    const _f = new BlackKey(keyboard, f);
    const g = new WhiteKey(eleParent, keyNames[4], bindKey[4]);
    const _g = new BlackKey(keyboard, g);
    const a = new WhiteKey(eleParent, keyNames[5], bindKey[5]);
    const _a = new BlackKey(keyboard, a);
    const b = new WhiteKey(eleParent, keyNames[6], bindKey[6]);
}